﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Diagnostics;
using System.Xml.Linq;
using System.Diagnostics.CodeAnalysis;

namespace LotroData
{
    /// <summary>
    /// Defines a LoTRO Guild. Provides methods for loading from the data.lotro.com XML stream.
    /// </summary>
    [DebuggerDisplay("Name = {Name}, Members = {Count}")]
    [SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix",
        Justification = "It would clutter the name.")]
    [SuppressMessage("Microsoft.Usage", "CA2237:MarkISerializableTypesWithSerializable",
        Justification = "As it can be only loaded from a previous XML stream, serialization is un-needed")]
    public class LotroGuild : Dictionary<string, LotroCharacter>
    {
        /// <summary>
        /// Gets the name of the guild.
        /// </summary>
        /// <value>A <see cref="System.String"/> value representing the name.</value>
        public string Name { get; protected set; }
        /// <summary>
        /// Gets or sets the theme of the guild.
        /// </summary>
        /// <value>A <see cref="LotroGuildTheme"/> value representing the guild theme.</value>
        public LotroGuildTheme GuildTheme { get; protected set; }
        /// <summary>
        /// Gets or sets the world where this guild is located.
        /// </summary>
        /// <value>A <see cref="LotroWorld"/> value representing the world.</value>
        public LotroWorld World { get; protected set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="LotroGuild"/> class.
        /// </summary>
        protected LotroGuild()
        {
            World = LotroWorld.Unknown;
        }

        /// <summary>
        /// Loads from a data.lotro.com XML stream.
        /// </summary>
        /// <param name="xmlContainer">The XML container.</param>
        /// <returns> A <see cref="LotroGuild"/> with the loaded XML data.</returns>
        public static LotroGuild LoadFromXml(XContainer xmlContainer)
        {
            if (xmlContainer.Element("apiresponse").Element("guild") == null) throw new ArgumentException("Invalid XML stream", "xmlContainer");

            var newGuild = new LotroGuild();
            newGuild.ParseXml(xmlContainer.Element("apiresponse").Element("guild"));
            return newGuild;
        }

        /// <summary>
        /// Parses the XML stream
        /// </summary>
        /// <param name="guildE">The guild <see cref="XElement"/>.</param>
        protected virtual void ParseXml(XElement guildE)
        {
            //Guild Attributes
            this.Name = guildE.Attribute("name").Value;
            this.World = guildE.Attribute("world").Value.ParseLotroEnum<LotroWorld>(true);
            this.GuildTheme = guildE.Attribute("theme").Value.ParseLotroEnum<LotroGuildTheme>(true);

            //Characters Element
            var charsE = guildE.Element("characters");
            //Character Enumerable
            var characters = charsE.Elements();
            foreach (var charac in characters)
            {
                var newChar = LotroCharacter.LoadFromXml(charac);
                this[newChar.Name] = newChar;
            }
        }

        /// <summary>
        /// Loads all the guilds characters with XML data from data.lotro.com
        /// </summary>
        /// <param name="request">The <see cref="LotroXmlRequest"/> that requests the XML streams.</param>
        public void LoadAllCharacterXml(LotroXmlRequest request)
        {
            foreach (var character in this)
            {
                var xDoc = request.GetCharacterSheet(character.Value.Name, character.Value.World);
                this[character.Key] = LotroCharacter.LoadFromXml(xDoc);
            }
        }
    }
}
